<template>
  <div class="channel">
    <van-popup v-model="show" position="bottom" :style="{ height: '80%' }">
      <!-- 我的频道 -->
      <van-cell title="我的频道">
        <template #default>
          <van-button
            class="mybtn"
            type="danger"
            round
            size="mini"
            plain
            @click="isEdit = true"
            v-if="isEdit === false"
            >编辑</van-button
          >
          <van-button
            class="mybtn"
            type="danger"
            round
            size="mini"
            plain
            v-if="isEdit === true"
            @click="isEdit = false"
            >完成</van-button
          >
        </template>
      </van-cell>
      <!-- {{ active }} -->
      <van-grid :gutter="3">
        <van-grid-item
          class="crossf"
          v-for="(item, index) in channelList"
          :key="index"
          @click="changeChannel(index)"
        >
          <template #text>
            <span class="corssw" :class="{ activcss: index === active }">{{
              item.name
            }}</span>
            <van-icon
              @click.stop="delChannel(item)"
              class="crosss"
              name="clear"
              v-show="isEdit && index != 0"
            />
          </template>
        </van-grid-item>
        <!-- {{tuijianChannel}} -->
      </van-grid>
      <!-- 频道推荐 -->
      <van-cell title="频道推荐" />
      <van-grid :gutter="3">
        <van-grid-item
          @click="addChannel(item)"
          :text="item.name"
          v-for="(item, index) in tuijianChannel"
          :key="index"
        />
      </van-grid>
    </van-popup>
  </div>
</template>

<script>
/*
我的频道渲染
 ..a.我的频道数据在父组件已经有了,也就是频道导航,先从父组件利用 :channelList="channelList" 传过来,在本页面接收用props,最后把数据在页面渲染(v-for)

推荐频道数据
  a.先封装一个全部列表的Api,可以不用携带token
  b.在data里面新建一个值来保存全部列表的数组,axios赋值给它,得到全部频道列表
  c.发现问题,要从所有频道-我的频道=推荐频道.
    定义一个计算属性computed(一旦计算完成，返回结果之后，这个结果会被缓存，下次再使用时，不会重新计算),功能实现,添加会自动跑上来
    在定义一个方法tuijianChannel(它返回的值可以直接渲染到页面上),利用map来得到我的频道的id,在上面封装的全部列表利用filter和includes来进行判断,判断我的频道有没有id重复的,有的话就不要返回,最后返回的是一个取反的数组,最后渲染到页面上
  
添加频道
    a给推荐频道添加点击事件,记得携带参数(item)
    b被点击的元素,push直接添加到我的频道中(利用了计算属性),问题:可以添加,但是一刷新就没有保存
    c将修改后的数据进行保存,添加和删除都要用到,可以封装一个方法,最后调用就可以了,
    d封装: 判断用户是否登录还是未登录(也就是判断它的token)
          未登录 也就是else,直接将修改后的数据保存到localstorage中,channels注意要和index页面的一致
          已经登录 确定是有token,请求服务器,封装一个批量修改用户列表(重置式),记得利用slice(1),不要截取第一个推荐,map循环得到里面的两个参数,频道的id和频道的顺序,+2是因为顺序是从1开始,然后推荐不包括在里面,所以是+2,
   e 最后调用这个封装的方法,保存起来 
   
   
   删除频道
      a给我的频道上的叉叉添加点击事件(记得携带index)index下标删除更简单,名称也可以删除元素,item.name 1
      b被点击的元素直接利用splice(index,1)来进行删除,然后调用封装的方法,保存起来.(发送的服务器请求是同一个)
   
   
去掉推荐的叉叉
  a v-show="isEdit && index != 0"判断叉叉的索引不能等于0,就可以除了叉叉其它的频道都会显示叉叉


  解决添加频道之后的 bug
   a 添加频道之后,除了当前页面有六个属性,点击其它添加的页面只有两个属性,手动给添加频道添加另外四个属性loading,finished,isLoading,articleList


高亮选中频道
  a 在我的频道添加样式,蓝色
  b 父页面把子标签active下标绑定,然后传入本页面,然后props接收,然后给要点击的频道选项添加点击事件:class="{ activcss: index === active }",也就是说父页面的id和index下标相等,父页面点击了本页面也会跟着高亮
  c 子页面点击父页面也要跟着高亮, 先在本页面添加点击事件,携带参数index,方式利用emit,this.$emit('update:active', index),来触发父组件的方法:active.sync="active",最后本页面点击,父页面也会跟着高亮


隐藏的bug
  点击删除频道,它会自动选中下一个频道,原因是事件冒泡,我们要阻止事件冒泡给我的频道点击事件添加一个.stop就可以了



*/

import { apiGetAllChannel, apiUpadateChannel } from '@/api/index.js'
import { getLocal, setLocal } from '@/utils/local.js'
export default {
  // 接收父组件传入的参数
  props: ['channelList', 'active'],
  data () {
    return {
      // 控制面板的显示与隐藏
      show: false,
      // 控制叉叉的显示与隐藏
      isEdit: false,
      // 所有频道列表
      allChannel: []
    }
  },

  methods: {
    // 修改选中的频道
    changeChannel (index) {
      // this.$parent.active = index // 这种写法不可以，因为它破坏了数据的单向性
      this.$emit('update:active', index)
    },
    // 删除频道
    delChannel (item) {
      // 根据名称或者下标删除元素
      // this.channelList.splice(index, 1)
      this.channelList.splice(item.name, 1)
      // 将修改之后的频道数据保存起来
      this.saveChannel()
    },
    // 添加频道
    addChannel (item) {
      // 给 item 添加额外属性
      this.$set(item, 'loading', false)
      this.$set(item, 'finished', false)
      this.$set(item, 'isLoading', false)
      this.$set(item, 'articleList', [])
      // 将 item 添加到我的频道中
      this.channelList.push(item)
      this.saveChannel()
    },
    // 保存修改后的频道数据
    async saveChannel () {
      // 得到用户的登录信息
      const token = getLocal('token')
      // 保存频道数据：
      if (token && token.token) {
        // 生成 mychannel slice从1截取到
        const myChannel = this.channelList.slice(1).map((item, index) => {
          return {
            id: item.id, // 频道的 id
            seq: index + 2 // 频道的顺序
          }
        })
        //    如果登录：
        //        将修改后的频道数据提交到服务器
        await apiUpadateChannel(myChannel)
      } else {
        //    如果未登录：
        //        将修改后的频道数据保存到 localstorage 中
        setLocal('channels', this.channelList)
      }
    },
    // 得到所有的频道数据
    async getAllChannel () {
      try {
        const res = await apiGetAllChannel()
        this.allChannel = res.data.data.channels
      } catch {
        this.$toast('请求错误')
      }
    }
  },
  computed: {
    // 定义一个频道推荐数据
    tuijianChannel () {
      // 得到我的频道所有数据的 id 集合
      const ids = this.channelList.map(item => {
        return item.id
      })
      // 得到所有的频道中 id 不在 ids 中的存在的元素
      const newArr = this.allChannel.filter(item => {
        return !ids.includes(item.id)
      })
      // 返回
      return newArr
    }
  },
  created () {
    // 得到所有的频道数据
    this.getAllChannel()
  }
}
</script>

<style lang="less" scoped>
.channel {
  .mybtn {
    padding: 4px 15px;
    /deep/ span.van-button__text {
      line-height: 24px;
    }
  }
  .crossf {
    position: relative;
    .crosss {
      position: absolute;
      top: 0px;
      right: 0px;
      font-size: 12px;
      color: #999;
    }
    .corssw {
      font-size: 12px;
      color: #646566;
    }
    /deep/ .activcss {
      color: skyblue;
    }
  }
}
</style>
